﻿using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZT.Core.Dto;
using ZT.Core.IService;
using ZT.Core.Model;
using ZT.Core.ORM;
using ZT.Core.Utility;

namespace ZT.Core.Service
{
    public class AuthUserService : ServiceBase,IAuthUser
    {
      
        private IUnitOfWork work = null;
        private IRepository<Auth_User> rpsAuthUser = null;
        private IRepository<Auth_UserProfile> rpsUserProfile = null;
        private IRepository<Auth_UserRole> rpsUserRole = null;
        private IRepository<Auth_Key> rpsKey = null;
        private IRepository<Auth_KeyDetail> rpsKeyDetail = null;
        private IRepository<Auth_RoleAuthScope> rpsRoleScope = null;
        private IRepository<Auth_Role> rpsRole = null;
        private IConfiguration config = null;
        public AuthUserService(IUnitOfWork unitwork, IConfiguration cfg)
        {
            work = unitwork;
            UnitOfWork = unitwork;
            config = cfg;
            rpsAuthUser = work.Repository<Auth_User>();
            rpsUserProfile = work.Repository<Auth_UserProfile>();
            rpsUserRole = work.Repository<Auth_UserRole>();
            rpsKey = work.Repository<Auth_Key>();
            rpsKeyDetail = work.Repository<Auth_KeyDetail>();
            rpsRoleScope = work.Repository<Auth_RoleAuthScope>();
            rpsRole = work.Repository<Auth_Role>();
        }
        /// <summary>
        /// 新建角色
        /// </summary>
        /// <param name="roleNew"></param>
        /// <returns></returns>
        public ResultModel<bool> AddRole(RoleNew roleNew)
        {
            try
            {
                var rolerps = work.Repository<Auth_Role>();
                if (rolerps.Any(q => q.RoleName == roleNew.RoleName))
                {
                    throw new Exception("角色名称:" + roleNew.RoleName + " 已经存在");
                }
                var dbrole = roleNew.MAPTO<Auth_Role>();
                rolerps.Insert(dbrole);
                work.Commit();

                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {

                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="roleID"></param>
        /// <returns></returns>
        public ResultModel<bool> DelRole(Guid roleId)
        {
            try
            {
                var role = rpsRole.GetModel(roleId);
                if (role == null)
                {
                    throw new Exception("角色不存在!");
                }
                rpsRole.Delete(role);
                rpsRoleScope.Delete(p => p.RoleId == roleId);
                rpsUserRole.Delete(p=>p.RoleId==roleId);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }

        /// <summary>
        /// 退出系统
        /// </summary>
        /// <returns></returns>
        public ResultModel<bool> UserLogout()
        {
            try
            {
                var user = rpsAuthUser.GetModel(AppUser.UserInfo.Id);
                if (user == null)
                {
                    throw new Exception("用户不存在!");
                }
                user.Token = "";
                rpsAuthUser.Update(user);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }

        /// <summary>
        /// 根据登陆的用户获取菜单
        /// </summary>
        /// <returns></returns>
        public ResultModel<IEnumerable<MenuView>> GetMenuByLogin()
        {
            try
            {
                //获取当前用户的角色
                var userRoles = rpsUserRole.Queryable(p => p.Login == AppUser.UserInfo.Login);
                var userRoleIds = userRoles.Select(s => s.RoleId);
                //获取当前用户的角色作用域
                var keys = rpsRoleScope.Queryable(p => userRoleIds.Contains(p.RoleId));
                var ckeys = keys.Select(s => s.AuthKey);

                var keybase = rpsKey.Queryable(p => ckeys.Contains(p.AuthKey)).OrderBy(o => o.OrderIndex);

                var moduleNames = keybase.Select(s => s.ModuleName).Distinct();
                var menuNames = keybase.Select(s => s.MenuName).Distinct();


                var modules = rpsKey.Queryable(q => moduleNames.Contains(q.ModuleName) && string.IsNullOrEmpty(q.MenuName) && string.IsNullOrEmpty(q.FunctionName)).Select(s => new { s.IconStr, s.ModuleName, s.OrderIndex });
                var menus = rpsKey.Queryable(q => moduleNames.Contains(q.ModuleName) && menuNames.Contains(q.MenuName) && string.IsNullOrEmpty(q.FunctionName)).Select(s => new { s.ModuleName, s.RoutUrl, s.OrderIndex, s.MenuName });

                var re = from md in modules
                         orderby md.OrderIndex
                         select new MenuView
                         {
                             ModuleName = md.ModuleName,
                             ImgUrl = md.IconStr,
                             MenuDetails = from m in menus
                                           where m.ModuleName == md.ModuleName
                                           orderby m.OrderIndex
                                           select new MenuDetail
                                           {
                                               MenuName = m.MenuName,
                                               RoutUrl = m.RoutUrl
                                           }
                         };


                return new ResultModel<IEnumerable<MenuView>>(re);
            }
            catch (Exception ex)
            {
                return new ResultModel<IEnumerable<MenuView>>(ex);
            }
        }
        /// <summary>
        /// 根据角色ID获取角色权限
        /// </summary>
        /// <param name="roleID"></param>
        /// <returns></returns>
        public ResultModel<IEnumerable<AuthView>> GetRoleAuth(Guid roleId)
        {
            try
            {
                var keys = rpsRoleScope.Queryable(p => p.RoleId == roleId);

                var keybase = rpsKey.Queryable();

                var moduleNames = keybase.Select(s => s.ModuleName).Distinct();
                var menuNames = keybase.Where(p => !string.IsNullOrEmpty(p.MenuName)).Select(s => s.MenuName).Distinct();


                var modules = rpsKey.Queryable(q => moduleNames.Contains(q.ModuleName) && string.IsNullOrEmpty(q.MenuName) && string.IsNullOrEmpty(q.FunctionName)).Select(s => new { s.IconStr, s.ModuleName, s.OrderIndex });
                var menus = rpsKey.Queryable(q => moduleNames.Contains(q.ModuleName) && menuNames.Contains(q.MenuName) && string.IsNullOrEmpty(q.FunctionName)).Select(s => new { s.ModuleName, s.RoutUrl, s.OrderIndex, s.MenuName });

                var funcs = keybase.Where(p => moduleNames.Contains(p.ModuleName) && menuNames.Contains(p.MenuName) && !string.IsNullOrEmpty(p.FunctionName)).Select(s => new { s.FunctionName, s.MenuName, s.OrderIndex, s.AuthKey });
                var re = from md in modules
                         orderby md.OrderIndex
                         select new AuthView
                         {
                             ModuleName = md.ModuleName,
                             AuthDetails = from m in menus
                                           where m.ModuleName == md.ModuleName
                                           orderby m.OrderIndex
                                           select new AuthDetails
                                           {
                                               MenuName = m.MenuName,
                                               AuthFuncs = from f in funcs
                                                           let isChecked = keys.Any(p => p.AuthKey == f.AuthKey)
                                                           where f.MenuName == m.MenuName
                                                           orderby m.OrderIndex
                                                           select new AuthFunc
                                                           {
                                                               FuncKey = f.AuthKey,
                                                               FuncName = f.FunctionName,
                                                               IsChecked = isChecked
                                                           }

                                           }
                         };
                return new ResultModel<IEnumerable<AuthView>>(re);
            }
            catch (Exception ex)
            {
                return new ResultModel<IEnumerable<AuthView>>(ex);
            }
        }
        /// <summary>
        /// 设置用户角色
        /// </summary>
        /// <param name="setRoles"></param>
        /// <returns></returns>
        public ResultModel<bool> SetLoginRole(SetLoginRoles setRoles)
        {
            try
            {
                var dbroles = new List<Auth_UserRole>();
                foreach (var roleId in setRoles.RoleIds)
                {
                    var urole = new Auth_UserRole
                    {
                        Login = setRoles.Login,
                        RoleId = roleId,
                    };
                    dbroles.Add(urole);
                };
                rpsUserRole.Delete(q => q.Login == setRoles.Login);
                rpsUserRole.Insert(dbroles);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="signin"></param>
        /// <returns></returns>
        public ResultModel<UserInfo> UserLogin(UserSignin signin)
        {
            try
            {
                var user = rpsAuthUser.GetModel(q => q.Login == signin.Login);
                if (user == null)
                {
                    throw new Exception("用户名或密码错误");
                }

                if (!string.Equals(user.Pwd, Command.EncodeBase64(Encoding.UTF8, signin.Pwd)))
                {
                    throw new Exception("用户名或密码错误");
                }
                var profile = rpsUserProfile.GetModel(q => q.UserId == user.Id);

                user.TokenValidTime = DateTime.Now.AddMinutes(30);

                user.Token = Command.CreateToken(64);
                rpsAuthUser.Update(user);
                work.Commit();
                return new ResultModel<UserInfo>(new UserInfo
                {
                    AuthUser = user.MAPTO<AuthUser>(),
                    UserProfile = new UserProfile
                    {
                        Id = profile.Id,
                        Email = profile.Email,
                        HeadImg = string.IsNullOrEmpty(profile.HeadImg) ? "" : config["ServerUrl"] + profile.HeadImg,
                        RelName = profile.RelName,
                        Tel = profile.Tel
                    }

                });
            }
            catch (Exception ex)
            {
                return new ResultModel<UserInfo>(ex);
            }
        }
        /// <summary>
        /// 根据ID获取个人资料
        /// </summary>
        /// <returns></returns>
        public ResultModel<UserProfile> GetUserProfile()
        {
            try
            {
                var profile = rpsUserProfile.GetModel(AppUser.UserProfile.Id);
                if (profile == null)
                    throw new Exception("未找到用户资料！");
                var re = profile.MAPTO<UserProfile>();
                re.HeadImg = string.IsNullOrEmpty(re.HeadImg) ? "" : config["ServerUrl"] + re.HeadImg;
                return new ResultModel<UserProfile>(re);
            }
            catch (Exception ex)
            {
                return new ResultModel<UserProfile>(ex);
            }

        }
        /// <summary>
        /// 设置个人资料
        /// </summary>
        /// <param name="para"></param>
        /// <returns></returns>
        public ResultModel<bool> SetProfile(SetUserProfile para)
        {
            try
            {
                var pro = rpsUserProfile.GetModel(AppUser.UserProfile.Id);
                if (string.IsNullOrEmpty(para.RelName))
                    throw new Exception("请填写姓名！");
                if (string.IsNullOrEmpty(para.Tel))
                    throw new Exception("请填写电话！");
                pro = para.CopyTo(pro);
                rpsUserProfile.Update(pro);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 新建用户
        /// </summary>
        /// <param name="userNew"></param>
        /// <returns></returns>
        public ResultModel<bool> AddUserInfo(AuthUserNew userNew)
        {
            try
            {
                var dbuser = new Auth_User()
                {
                    Login = userNew.Login,
                    Pwd = Command.EncodeBase64(Encoding.UTF8, "123456"),
                    TokenValidTime = DateTime.Now,
                    Token = "",
                    Creator = AppUser.UserInfo.Login,
                    State = Enums.UserState.Normal,
                    CreateTime=DateTime.Now
                };
                var profile = new Auth_UserProfile()
                {
                    RelName = userNew.RelName,
                    UserId=dbuser.Id,
                    HeadImg= "",
                    Tel = userNew.Tel,
                    Email=userNew.Email
                };
                if (string.IsNullOrEmpty(userNew.Login))
                {
                    throw new Exception("用户名密码均不能为空");
                }
                if (rpsAuthUser.Any(q => q.Login == userNew.Login))
                {
                    throw new Exception("用户名：" + userNew.Login + "已经存在");
                }
                rpsUserProfile.Insert(profile);
                rpsAuthUser.Insert(dbuser);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public ResultModel<bool> DelAuthUser(Guid userID)
        {
            try
            {
                var dbuser = rpsAuthUser.GetModel(userID);
                if (dbuser == null)
                {
                    throw new Exception("用户不存在");
                }
                if (dbuser.Login == "Admin")
                {
                    throw new Exception("系统内置超级用户不允许删除");
                }

                rpsAuthUser.Delete(dbuser);
                rpsUserProfile.Delete(q => q.UserId == dbuser.Id);
                rpsUserRole.Delete(q => q.Login == dbuser.Login);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 分页获取用户信息
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public ResultModel<Pager<UserPage>> GetUserPages(PagerQuery<UserPageQuery> query)
        {
            var users = rpsAuthUser.Queryable();
            var profile = rpsUserProfile.Queryable();
            var retemp = from u in users
                         let pro = profile.FirstOrDefault(p => p.UserId == u.Id)
                         where u.Login.Contains(query.Query.KeyWord) || pro.RelName.Contains(query.Query.KeyWord) || query.Query.KeyWord == string.Empty
                         orderby u.CreateTime
                         select new UserPage
                         {
                             UserId = u.Id,
                             Login = u.Login,
                             UserState = u.State,
                             Tel = pro.Tel,
                             Email = pro.Email,
                             RelName = pro.RelName,
                             HeadImg = string.IsNullOrEmpty(pro.HeadImg) ? "" : config["ServerUrl"] + pro.HeadImg
                         };
            var re = new Pager<UserPage>().GetCurrentPage(retemp,query.PageSize,query.PageIndex);
            return new ResultModel<Pager<UserPage>>(re);
        }
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="pwdChange"></param>
        /// <returns></returns>
        public ResultModel<bool> ChangePwd(UserPwdChange pwdChange)
        {
            try
            {
                var user = AppUser.UserInfo;
                if (!string.Equals(user.Pwd, Command.EncodeBase64(Encoding.UTF8, pwdChange.OldPwd)))
                {
                    throw new Exception("原密码输入错误");
                }
                user.Pwd = Command.EncodeBase64(Encoding.UTF8, pwdChange.Pwd);
                user.IsTip = false;
                rpsAuthUser.Update(user);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="UserID"></param>
        /// <returns></returns>
        public ResultModel<bool> ResetPwd(Guid userID)
        {
            try
            {
                var user = rpsAuthUser.GetModel(userID);
                if (user == null)
                {
                    throw new Exception("该用户不存在");
                }
                user.Pwd = Command.EncodeBase64(Encoding.UTF8, "123456");
                user.IsTip = true;
                rpsAuthUser.Update(user);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 不再提示
        /// </summary>
        /// <returns></returns>
        public ResultModel<bool> NotTip()
        {
            try
            {
                var user = AppUser.UserInfo;
                user.IsTip = false;
                rpsAuthUser.Update(user);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
        /// <summary>
        /// 设置角色权限
        /// </summary>
        /// <param name="roleAuth"></param>
        /// <returns></returns>
        public ResultModel<bool> SetRoleAuth(RoleAuthSet roleAuth)
        {
            try
            {
                var dbrauth = new List<Auth_RoleAuthScope>();
                foreach (var rauth in roleAuth.AuthKeys)
                {
                    var irauth = new Auth_RoleAuthScope
                    {
                        AuthKey = rauth,
                        RoleId = roleAuth.RoleId,
                    };
                    dbrauth.Add(irauth);
                }
                rpsRoleScope.Delete(q => q.RoleId == roleAuth.RoleId);
                rpsRoleScope.Insert(dbrauth);
                work.Commit();
                return new ResultModel<bool>(true);
            }
            catch (Exception ex)
            {
                return new ResultModel<bool>(ex);
            }
        }
    }
}
